using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

using libsecondlife;

using Feathertail;
using Feathertail.Tracker;
using Feathertail.Tracker.Filters;

namespace NestBox
{
    class Scan : Feathertail.Command
    {
        private FeathertailClient _Client;

        #region Command Members

        public void Setup(FeathertailClient Client)
        {
            _Client = Client;
        }

        public string HandleInput(string[] CmdLine)
        {
            if (CmdLine.Length < 2)
            {
                return GetHelpText();
            }

            ObjectOverlord objOverlord = ((ObjectOverlord)_Client.Objects);
            List<ObjectFilter> Filters = new List<ObjectFilter>();

            bool DisplayUUID = false;
            bool DisplayLocalID = false;
            bool DisplayPosition = false;
            bool DisplayDistance = false;

            for( int i=0; i<CmdLine.Length; i++ )
            {
                if (CmdLine[i].ToLower().Equals("-s") || CmdLine[i].ToLower().Equals("-status"))
                {
                    Dictionary<ObjectOverlord.TrackerStatus, object> status = objOverlord.GetTrackerStatus();

                    StringBuilder sboutput = new StringBuilder();
                    sboutput.AppendLine("Last update received: " + ((DateTime)status[ObjectOverlord.TrackerStatus.LastReceivedPacket]));
                    sboutput.AppendLine("Number of sims with object data: " + status[ObjectOverlord.TrackerStatus.SimsTracked]);
                    sboutput.AppendLine("Number of objects in the current sim: " + status[ObjectOverlord.TrackerStatus.CurrentSimObjects]);
                    return sboutput.ToString();
                }

                switch (CmdLine[i].ToLower())
                {
                    case "-uuid":
                        DisplayUUID = true;
                        break;

                    case "-localid":
                        DisplayLocalID = true;
                        break;

                    case "-position":
                        DisplayPosition = true;
                        break;

                    case "-distance":
                        DisplayDistance = true;
                        break;

                    case "-name":
                        Filters.Add(new NameFilter(CmdLine[++i], NameFilter.TextMatchType.Contains, false));
                        break;

                    case "-noav":
                        Filters.Add(new TypeFilter(TypeFilter.ObjectType.Avatar, TypeFilter.FilterType.Exclude));
                        break;

                    case "-noprim":
                        Filters.Add(new TypeFilter(TypeFilter.ObjectType.Primitive, TypeFilter.FilterType.Exclude));
                        break;

                    default:
                        double radius;
                        if (double.TryParse(CmdLine[i], out radius))
                        {
                            Filters.Add(new DistanceFilter(radius));
                        }
                        break;
                }
                
            }

            string output = Environment.NewLine;


            // Lets go filtering!!!
            List<LLObject> ScanResults;
            ScanResults = objOverlord.FilterObjects(Filters);


            foreach (LLObject obj in ScanResults)
            {
                if (DisplayDistance)
                {
                    output += "[Distance:" + _Client.Self.Position.GetDistanceTo(obj.Position).ToString("0000.000") + "]\t";
                }

                if (DisplayPosition)
                {
                    output += "[Position:" + obj.Position.ToString() + "]\t";
                }

                if (DisplayLocalID)
                {
                    output += "[LID:" + obj.LocalID + "]\t";
                }

                if (DisplayUUID)
                {
                    output += "[UUID:" + obj.ID + "]\t";
                }

                if (obj.PropertiesFamily.Name != null)
                {
                    output += obj.PropertiesFamily.Name;
                }

                output += Environment.NewLine;
            }

            return output;

        }

        public string[] GetCommandStrings()
        {
            return new string[] { "scan" };
        }

        public string GetSummaryText()
        {
            return "Scan for objects.";
        }

        public string GetHelpText()
        {
            return GetSummaryText()
                + Environment.NewLine + "Usage: SCAN <options> [radius] "
                + Environment.NewLine + "General Options:"
                + Environment.NewLine + "\t -status \t Display Scanner Status"
                + Environment.NewLine + "Display Options:"
                + Environment.NewLine + "\t -uuid \t Display UUID"
                + Environment.NewLine + "\t -localid \t Display LocalID"
                + Environment.NewLine + "\t -distance \t Display Distance"
                + Environment.NewLine + "\t -position \t Display Position"
                + Environment.NewLine + "Filter Options:"
                + Environment.NewLine + "\t -name \"text\" \t Filter based on \"test\" in name"
                + Environment.NewLine + "\t -noav \t Do not include Avatars"
                + Environment.NewLine + "\t -noprim \t Do not include Prims";
        }

        #endregion
    }
}
